﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using Entersoft.Data.DotNetDAL.SQL;

namespace BLL
{
    public class Usuarios : Common
    {
        public Usuario Usuario { get; private set; }

        public Usuario ObtenerUsuario(int UserId, ref string errMessage)
        {
            Usuario retorno = null;

            foreach (var usrTmp in ObtenerUsuarios(ref errMessage))
            {
                if (usrTmp.UserId != UserId) continue;

                retorno = usrTmp;
                break;
            }

            return retorno;
        }

        public Usuario ObtenerUsuario(string NombreCorto, ref string errMessage)
        {
            Usuario retorno = null;

            foreach (var usrTmp in ObtenerUsuarios(ref errMessage))
            {
                if (usrTmp.NombreCorto != NombreCorto) continue;
                
                retorno = usrTmp;
                break;
            }

            return retorno;
        }

        public bool CompararClave(int UserId, string Clave, ref string errMessage)
        {
            var usrTmp = ObtenerUsuario(UserId, ref errMessage);

            Usuario = usrTmp;

            return usrTmp != null && usrTmp.Clave.Equals(Clave);
        }

        public bool CompararClave(string nombreCorto, string clave, ref string errMessage)
        {
            var usrTmp = ObtenerUsuario(nombreCorto, ref errMessage);

            Usuario = usrTmp;

            return usrTmp != null && usrTmp.Clave.Equals(clave);
        }

        public static IList<Usuario> ObtenerLideres(int? LiderId, ref string errMessage)
        {
            var tmpLista = new List<Usuario>();

            tmpLista.AddRange(ObtenerLideres(2, LiderId, ref errMessage)); // Lider Externo

            if (string.IsNullOrEmpty(errMessage))
                tmpLista.AddRange(ObtenerLideres(3, LiderId, ref errMessage)); // Lider Interno

            return tmpLista;
        }

        public static IList<Usuario> ObtenerLideres(int PerfilId, int? LiderId, ref string errMessage)
        {
            var listaLideres = new List<Usuario>();

            var listaUsuarios = ObtenerUsuarios(PerfilId, LiderId, ref errMessage);

            foreach (var tmpUsuario in listaUsuarios)
                listaLideres.Add(tmpUsuario);

            return listaLideres;
        }

        public static IList<Usuario> ObtenerUsuarios(ref string errMessage)
        {
            return ObtenerUsuarios(null, null, ref errMessage);
        }
 
        public static IList<Usuario> ObtenerUsuarios(int? PerfilId, int? UsuarioId, ref string errMessage)
        {
           var retorno = new List<Usuario>();

           var objRP = new Entersoft.Data.DotNetResponse.SQL.Persistence { StoredProcedure = "SP_GET_USUARIOS" };

            using (var objConn = new Persistence(false, ConnDB))
            {
                objRP.AddParametro(PerfilId);
                objRP.AddParametro(UsuarioId);

                objConn.ExecuteDataTable(ref objRP);

                if (!objRP.TieneErrores)
                {
                    if (objRP.DataTable != null)
                    {
                        foreach (DataRow row in objRP.DataTable.Rows)
                        {
                            var usrTmp = new Usuario(Convert.ToInt32(row["usuarios_Id"].ToString()),
                                                     row["usuarios_NombreCorto"].ToString(),
                                                     row["usuarios_NombreCompleto"].ToString(),
                                                     row["usuarios_Clave"].ToString(),
                                                     Convert.ToInt32(row["usuarios_PerfilId"]),
                                                     (row["usuarios_Depende"].Equals(DBNull.Value) ? (int?)null : Convert.ToInt32(row["usuarios_Depende"])));

                            retorno.Add(usrTmp);
                        }
                    }
                }
                else
                    errMessage = objRP.Errores;
            }

            objRP.Dispose();

            return retorno;
        }

        public bool EliminarUsuario(int UserId)
        {
            bool retorno = false;

            var objRP = new Entersoft.Data.DotNetResponse.SQL.Persistence { StoredProcedure = "sp_del_Usuario" };

            objRP.AddParametro(UserId);
            objRP.AddParametro(-99);
            objRP.AddParametro("");

            using (var objConn = new Persistence(true, ConnDB))
            {
                objConn.ExecuteNonQuery(ref objRP);

                Mensaje = objRP.Parametro[2].ToString();

                if (!objRP.TieneErrores)
                {
                    retorno = Convert.ToInt32(objRP.Parametro[1]) == 0;
                    objConn.Commit();
                }
            }
            

            objRP.Dispose();

            return retorno;
        }

        public bool GrabarUsuario(Usuario user)
        {
            return GrabarUsuario(user, null);
        }

        public bool GrabarUsuario(Usuario user, string periodo = null)
        {
            bool retorno = false;

            var objRP = new Entersoft.Data.DotNetResponse.SQL.Persistence { StoredProcedure = "sp_ins_Usuario" };

            objRP.AddParametro(user.NombreCorto);
            objRP.AddParametro(user.NombreCompleto);
            objRP.AddParametro(user.Clave);
            objRP.AddParametro(user.PerfilId);

            if (user.Lider != null)
                objRP.AddParametro(user.Lider.UserId);
            else
                objRP.AddParametro(null);

            objRP.AddParametro(periodo);
            
            objRP.AddParametro(null); // Retorno
            objRP.AddParametro(null); // Mensaje

            using (var objConn = new Persistence(true, ConnDB))
            {
                objConn.ExecuteNonQuery(ref objRP);

                if (!objRP.TieneErrores)
                {
                    retorno = Convert.ToInt32(objRP.Parametro[6]).Equals(0);
                    Mensaje = objRP.Parametro[7].ToString();
                }
                else
                    Mensaje = objRP.Errores;

                if (retorno)
                    objConn.Commit();
            }

            objRP.Dispose();

            return retorno;
        }

        public bool ActualizarUsuario(Usuario user)
        {
            bool retorno = false;

            var objRP = new Entersoft.Data.DotNetResponse.SQL.Persistence { StoredProcedure = "sp_upd_Usuario" };

            objRP.AddParametro(user.UserId);
            objRP.AddParametro(user.NombreCompleto);
            objRP.AddParametro(user.Clave);
            objRP.AddParametro(user.PerfilId);

            if (user.Lider != null)
                objRP.AddParametro(user.Lider.UserId);
            else
                objRP.AddParametro(null);

            objRP.AddParametro(null);
            objRP.AddParametro(null);

            using (var objConn = new Persistence(true, ConnDB))
            {
                objConn.ExecuteNonQuery(ref objRP);

                Mensaje = objRP.Parametro[6].ToString();

                if (!objRP.TieneErrores)
                {
                    retorno = Convert.ToInt32(objRP.Parametro[5]) == 0;

                    objConn.Commit();
                }
            }

            objRP.Dispose();

            return retorno;
        }
    }

    [Serializable]
    public class Usuario
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        private int mUserId;

        [EditorBrowsable(EditorBrowsableState.Never)]
        private string mNombreCorto;

        [EditorBrowsable(EditorBrowsableState.Never)]
        private string mNombreCompleto;

        [EditorBrowsable(EditorBrowsableState.Never)]
        private string mClave;

        [EditorBrowsable(EditorBrowsableState.Never)]
        private int mPerfilID;

        [EditorBrowsable(EditorBrowsableState.Never)]
        private int? mLiderId;

        public Usuario()
        {
            
        }

        public Usuario(string NombreCorto, string NombreCompleto, string Clave, int PerfilID, int? Depende): this(-999, NombreCorto, NombreCompleto, Clave, PerfilID, Depende)
        {
        }

        public Usuario(int UserId, string NombreCorto, string NombreCompleto, string Clave, int PerfilID, int? Lider)
        {
            mUserId = UserId;
            mNombreCorto = NombreCorto;
            mNombreCompleto = NombreCompleto;
            mClave = Clave;
            mPerfilID = PerfilID;
            mLiderId = Lider;
        }

        public int UserId
        {
            get { return mUserId; }
            set { mUserId = value; }
        }

        public string NombreCorto
        {
            get { return mNombreCorto; }
            set { mNombreCorto = value; }
        }

        public string NombreCompleto
        {
            get { return mNombreCompleto; }
            set { mNombreCompleto = value; }
        }

        public string Clave
        {
            get { return mClave; }
            set { mClave = value; }
        }

        public int PerfilId
        {
            get { return mPerfilID; }
            set { mPerfilID = value; }
        }

        public Usuario Lider
        {
            get
            {
                Usuario retorno = null;

                var errMessage = "";

                var listaLideres = Usuarios.ObtenerLideres(mLiderId, ref errMessage);

                if (string.IsNullOrEmpty(errMessage))
                    foreach (var tmpUsuario in listaLideres)
                        if (tmpUsuario.UserId == mLiderId)
                            retorno = tmpUsuario;

                return retorno;
            }
        }

        public void SetLider(int? LiderId)
        {
            mLiderId = LiderId;
        }

        public Perfil Perfil
        {
            get
            {
                Perfil retorno = null;

                var tmpPerfiles = Perfiles.ObtenerPerfiles();

                foreach (var tmpPerfil in tmpPerfiles)
                {
                    if (tmpPerfil.PerfilId != PerfilId) continue;

                    retorno = tmpPerfil;
                    break;
                }

                return retorno;
            }
        } 
    }
}
